﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SlickGridNet
{
	public class SlickOptions : OptionsBase
	{
		#region FieldNames
		protected const string AsyncEditorLoadingField = "asyncEditorLoading";
		protected const string AsyncEditorLoadDelayField = "asyncEditorLoadDelay";
		protected const string AsyncPostRenderDelayField = "asyncPostRenderDelay";
		protected const string AutoEditField = "autoEdit";
		protected const string AutoHeightField = "autoHeight";
		protected const string CellFlashingCssClassField = "cellFlashingCssClass";
		protected const string CellHighlightCssClassField = "cellHighlightCssClass";
		protected const string DataItemColumnValueExtractorField = "dataItemColumnValueExtractor";
		protected const string DefaultColumnWidthField = "defaultColumnWidth";
		protected const string DefaultFormatterField = "defaultFormatter";
		protected const string EditableField = "editable";
		protected const string EditCommandHandlerField = "editCommandHandler";
		protected const string EditorFactoryField = "editorFactory";
		protected const string EditorLockField = "editorLock";
		protected const string EnableAddRowField = "enableAddRow";
		protected const string EnableAsyncPostRenderField = "enableAsyncPostRender";
		protected const string EnableCellRangeSelectionField = "enableCellRangeSelection";
		protected const string EnableCellNavigationField = "enableCellNavigation";
		protected const string EnableColumnReorderField = "enableColumnReorder";
		protected const string EnableRowReorderingField = "enableRowReordering";
		protected const string EnableTextSelectionOnCellsField = "enableTextSelectionOnCells";
		protected const string ExplicitInitializationField = "explicitInitialization";
		protected const string ForceFitColumnsField = "forceFitColumns";
		protected const string ForceSyncScrollingField = "forceSyncScrolling";
		protected const string FormatterFactoryField = "formatterFactory";
		protected const string FullWidthRowsField = "fullWidthRows";
		protected const string HeaderRowHeightField = "headerRowHeight";
		protected const string LeaveSpaceForNewRowsField = "leaveSpaceForNewRows";
		protected const string MultiColumnSortField = "multiColumnSort";
		protected const string MultiSelectField = "multiSelect";
		protected const string RowHeightField = "rowHeight";
		protected const string SelectedCellCssClassField = "selectedCellCssClass";
		protected const string ShowHeaderRowField = "showHeaderRow";
		protected const string SyncColumnCellResizeField = "syncColumnCellResize";
		protected const string TopPanelHeightField = "topPanelHeight";
		#endregion FieldNames

		#region Properties

		/// <summary>
		/// Makes cell editors load asynchronously after a small delay. This greatly increases keyboard navigation speed.
		/// </summary>
		public bool AsyncEditorLoading
		{
			get { return (bool)Get(AsyncEditorLoadingField); }
			set { Set(AsyncEditorLoadingField, value); }
		}

		/// <summary>
		/// Delay after which cell editor is loaded. Ignored unless asyncEditorLoading is true.
		/// </summary>
		public int AsyncEditorLoadDelay
		{
			get { return (int)Get(AsyncEditorLoadDelayField); }
			set { Set(AsyncEditorLoadDelayField, value); }
		}

		public int AsyncPostRenderDelay
		{
			get { return (int)Get(AsyncPostRenderDelayField); }
			set { Set(AsyncPostRenderDelayField, value); }
		}

		/// <summary>
		/// Cell will not automatically go into edit mode when selected.
		/// </summary>
		public bool AutoEdit
		{
			get { return (bool)Get(AutoEditField); }
			set { Set(AutoEditField, value); }
		}

		/// <summary>
		/// This disables vertical scrolling.
		/// </summary>
		public bool AutoHeight
		{
			get { return (bool)Get(AutoHeightField); }
			set { Set(AutoHeightField, value); }
		}

		/// <summary>
		/// A CSS class to apply to flashing cells via flashCell().
		/// </summary>
		public string CellFlashingCssClass
		{
			get { return Get(CellFlashingCssClassField) as string; }
			set { Set(CellFlashingCssClassField, value); }
		}

		/// <summary>
		/// A CSS class to apply to cells highlighted via setHighlightedCells().
		/// </summary>
		public string CellHighlightCssClass
		{
			get { return Get(CellHighlightCssClassField) as string; }
			set { Set(CellHighlightCssClassField, value); }
		}

		public string DataItemColumnValueExtractor
		{
			get { return Get(DataItemColumnValueExtractorField) as string; }
			set { Set(DataItemColumnValueExtractorField, value); }
		}

		public int DefaultColumnWidth
		{
			get { return (int)Get(DefaultColumnWidthField); }
			set { Set(DefaultColumnWidthField, value); }
		}

		public string DefaultFormatter
		{
			get { return Get(DefaultFormatterField) as string; }
			set { Set(DefaultFormatterField, value); }
		}

		public bool Editable
		{
			get { return (bool)Get(EditableField); }
			set { Set(EditableField, value); }
		}

		/// <summary>
		/// Not listed as a default under options in slick.grid.js
		/// </summary>
		public string EditCommandHandler
		{
			get { return Get(EditCommandHandlerField) as string; }
			set { Set(EditCommandHandlerField, value); }
		}

		/// <summary>
		/// A factory object responsible to creating an editor for a given cell. Must implement getEditor(column).
		/// </summary>
		public string EditorFactory
		{
			get { return Get(EditorFactoryField) as string; }
			set { Set(EditorFactoryField, value); }
		}

		/// <summary>
		/// A Slick.EditorLock instance to use for controlling concurrent data edits.
		/// </summary>
		public string EditorLock
		{
			get { return Get(EditorLockField) as string; }
			set { Set(EditorLockField, value); }
		}

		/// <summary>
		/// If true, a blank row will be displayed at the bottom - typing values in that row will add a new one. 
		/// Must subscribe to onAddNewRow to save values.
		/// </summary>
		public bool EnableAddRow
		{
			get { return (bool)Get(EnableAddRowField); }
			set { Set(EnableAddRowField, value); }
		}

		/// <summary>
		/// If true, async post rendering will occur and asyncPostRender delegates on columns will be called.
		/// </summary>
		public bool EnableAsyncPostRender
		{
			get { return (bool)Get(EnableAsyncPostRenderField); }
			set { Set(EnableAsyncPostRenderField, value); }
		}

		/// <summary>
		/// **WARNING**: Not contained in SlickGrid 2.1, may be deprecated
		/// </summary>
		public string EnableCellRangeSelection
		{
			get { return Get(EnableCellRangeSelectionField) as string; }
			set { Set(EnableCellRangeSelectionField, value); }
		}

		/// <summary>
		/// Appears to enable cell virtualisation for optimised speed with large datasets
		/// </summary>
		public bool EnableCellNavigation
		{
			get { return (bool)Get(EnableCellNavigationField); }
			set { Set(EnableCellNavigationField, value); }
		}

		public bool EnableColumnReorder
		{
			get { return (bool)Get(EnableColumnReorderField); }
			set { Set(EnableColumnReorderField, value); }
		}

		/// <summary>
		/// **WARNING**: Not contained in SlickGrid 2.1, may be deprecated
		/// </summary>
		public string EnableRowReordering
		{
			get { return Get(EnableRowReorderingField) as string; }
			set { Set(EnableRowReorderingField, value); }
		}

		public bool EnableTextSelectionOnCells
		{
			get { return (bool)Get(EnableTextSelectionOnCellsField); }
			set { Set(EnableTextSelectionOnCellsField, value); }
		}

		/// <summary>
		/// See: Example: Explicit Initialization
		/// </summary>
		public bool ExplicitInitialization
		{
			get { return (bool)Get(ExplicitInitializationField); }
			set { Set(ExplicitInitializationField, value); }
		}

		/// <summary>
		/// Force column sizes to fit into the container (preventing horizontal scrolling). 
		/// Effectively sets column width to be 1/Number of Columns which on small containers may not be desirable
		/// </summary>
		public bool ForceFitColumns
		{
			get { return (bool)Get(ForceFitColumnsField); }
			set { Set(ForceFitColumnsField, value); }
		}

		public bool ForceSyncScrolling
		{
			get { return (bool)Get(ForceSyncScrollingField); }
			set { Set(ForceSyncScrollingField, value); }
		}

		/// <summary>
		/// A factory object responsible to creating a formatter for a given cell. Must implement getFormatter(column).
		/// </summary>
		public string FormatterFactory
		{
			get { return Get(FormatterFactoryField) as string; }
			set { Set(FormatterFactoryField, value); }
		}

		/// <summary>
		/// Will expand the table row divs to the full width of the container, table cell divs will remain aligned to the left
		/// </summary>
		public bool FullWidthRows
		{
			get { return (bool)Get(FullWidthRowsField); }
			set { Set(FullWidthRowsField, value); }
		}

		public int HeaderRowHeight
		{
			get { return (int)Get(HeaderRowHeightField); }
			set { Set(HeaderRowHeightField, value); }
		}

		public bool LeaveSpaceForNewRows
		{
			get { return (bool)Get(LeaveSpaceForNewRowsField); }
			set { Set(LeaveSpaceForNewRowsField, value); }
		}

		/// <summary>
		/// See: Example: Multi-Column Sort
		/// </summary>
		public bool MultiColumnSort
		{
			get { return (bool)Get(MultiColumnSortField); }
			set { Set(MultiColumnSortField, value); }
		}

		public bool MultiSelect
		{
			get { return (bool)Get(MultiSelectField); }
			set { Set(MultiSelectField, value); }
		}

		public int RowHeight
		{
			get { return (int)Get(RowHeightField); }
			set { Set(RowHeightField, value); }
		}

		public string SelectedCellCssClass
		{
			get { return Get(SelectedCellCssClassField) as string; }
			set { Set(SelectedCellCssClassField, value); }
		}

		public bool ShowHeaderRow
		{
			get { return (bool)Get(ShowHeaderRowField); }
			set { Set(ShowHeaderRowField, value); }
		}

		/// <summary>
		/// If true, the column being resized will change its width as the mouse is dragging the resize handle. 
		/// If false, the column will resize after mouse drag ends.
		/// </summary>
		public bool SyncColumnCellResize
		{
			get { return (bool)Get(SyncColumnCellResizeField); }
			set { Set(SyncColumnCellResizeField, value); }
		}

		public int TopPanelHeight
		{
			get { return (int)Get(TopPanelHeightField); }
			set { Set(TopPanelHeightField, value); }
		}

		#endregion

		public SlickOptions()
		{
			InitDefaultValues();
		}

		protected void InitDefaultValues()
		{
			defaultValues.Add(AsyncEditorLoadingField, false);
			defaultValues.Add(AsyncEditorLoadDelayField, 100);
			defaultValues.Add(AsyncPostRenderDelayField, 50);
			defaultValues.Add(AutoEditField, true);
			defaultValues.Add(AutoHeightField, false);
			defaultValues.Add(CellFlashingCssClassField, "flashing");
			defaultValues.Add(CellHighlightCssClassField, "selected");
			defaultValues.Add(DataItemColumnValueExtractorField, null);
			defaultValues.Add(DefaultColumnWidthField, 80);
			defaultValues.Add(DefaultFormatterField, "defaultFormatter");
			defaultValues.Add(EditableField, false);
			defaultValues.Add(EditCommandHandlerField, "queueAndExecuteCommand");
			defaultValues.Add(EditorFactoryField, null);
			defaultValues.Add(EditorLockField, "Slick.GlobalEditorLock");
			defaultValues.Add(EnableAddRowField, false);
			defaultValues.Add(EnableAsyncPostRenderField, false);
			defaultValues.Add(EnableCellRangeSelectionField, null);
			defaultValues.Add(EnableCellNavigationField, true);
			defaultValues.Add(EnableColumnReorderField, true);
			defaultValues.Add(EnableRowReorderingField, null);
			defaultValues.Add(EnableTextSelectionOnCellsField, false);
			defaultValues.Add(ExplicitInitializationField, false);
			defaultValues.Add(ForceFitColumnsField, false);
			defaultValues.Add(ForceSyncScrollingField, false);
			defaultValues.Add(FormatterFactoryField, null);
			defaultValues.Add(FullWidthRowsField, false);
			defaultValues.Add(HeaderRowHeightField, 25);
			defaultValues.Add(LeaveSpaceForNewRowsField, false);
			defaultValues.Add(MultiColumnSortField, false);
			defaultValues.Add(MultiSelectField, true);
			defaultValues.Add(RowHeightField, 25);
			defaultValues.Add(SelectedCellCssClassField, "selected");
			defaultValues.Add(ShowHeaderRowField, false);
			defaultValues.Add(SyncColumnCellResizeField, false);
			defaultValues.Add(TopPanelHeightField, 25);

		}
	}
}